<template>
  <div>
    <!-- 地图容器，占满整个宽度和高度 -->
    <div id="map" style="width: 100vw; height: 100vh" ></div>
    <!-- 地理标记，带有动画的图片 -->
    <div id="geo-marker" class="css_animation">
      <img :src="myplanImg" style="width: 3vw" />
    </div>
    <!-- 用于显示速度的测量提示 -->
    <div class="measuretip" id="speed"></div>
  </div>
  <!-- 固定容器，用于搜索和用户交互 -->
  <div class="fixed z-[999] w-[500px] top-[10px] left-[40px] rounded-md">
    <!-- 用户名输入框 -->
    <el-input
      style="width: 55%"
      placeholder="请输入内容"
      v-model="user.name"
      class="input-with-select"
    >
    </el-input>
    <!-- 按钮，用于搜索用户数据 -->

    <el-button @click="getUser"> 搜索人员数据 </el-button>
    <br />
    <!-- 下拉框，用于选择用户 -->
    <el-select style="width: 55%" v-model="selectedUser" placeholder="请选择">
      <el-option
        v-for="item in userList"
        :key="item.id"
        :label="item.name"
        :value="item.id"
      >
        <!-- 用户名 -->
        <span style="float: left">{{ item.name }}&emsp;</span>
        <!-- 用户ID -->
        <span style="float: right; color: #8492a6; font-size: 13px">{{
          item.id
        }}</span>
      </el-option>
    </el-select>

    <!-- 按钮，触发人员轨迹查询弹窗 -->
    <el-button @click="openPositionDialog"> 人员轨迹查询 </el-button>

    <div style="display: flex; justify-content: flex-start">
      <el-button @click="map2DTO3D">二三维切换</el-button>

      <el-button type="primary" @click="openAddUserPositionDialog"
        >添加人员信息</el-button
      >
      <el-dialog v-model="showAddUserPositionDialog" title="添加位置">
        <el-form :model="position">
          <el-form-item label="uid">
            <el-input v-model="position.uid" required />
          </el-form-item>
          <el-form-item label="纬度">
            <el-input v-model="position.lat" required />
          </el-form-item>
          <el-form-item label="经度">
            <el-input v-model="position.lon" required />
          </el-form-item>
          <el-form-item label="时间">
            <el-input v-model="position.createTime" required />
          </el-form-item>
          <!-- 其他位置信息的输入框 -->

          <el-form-item>
            <el-button type="primary" @click="addUserPosition"
              >添加位置</el-button
            >
          </el-form-item>
        </el-form>
      </el-dialog>
      <!-- 其他页面内容 -->
    </div>

    <!--二维图像绘制-->
    <div style="display: flex; justify-content: flex-start">
      <!-- 下拉框，用于选择绘制类型 -->
      <el-select
        style="width: 55%"
        v-model="selectedShape"
        placeholder="请选择绘制图形"
      >
        <el-option
          v-for="option in shapeOptions"
          :key="option.value"
          :label="option.label"
          :value="option.value"
        >
          <span class="float-left">{{ option.label }}</span>
        </el-option>
      </el-select>

      <el-button @click="drawIn2d(selectedShape, 'rgba(255, 0, 0, 0.5)')">
        开始绘制
      </el-button>
    </div>

    <div style="display: flex; justify-content: flex-start">
      <!-- 下拉框，用于选择绘制类型 -->
      <el-select
        style="width: 55%"
        v-model="selectedIcon"
        placeholder="请选择添加图标"
      >
        <el-option
          v-for="option in iconOptions"
          :key="option.value"
          :label="option.label"
          :value="option.value"
        >
          <span class="float-left">{{ option.label }}</span>
        </el-option>
      </el-select>

      <el-button @click="drawIconIn2d(selectedIcon)"> 新增图标 </el-button>
    </div>

    <div
      style="
        display: flex;
        justify-content: flex-start;
        line-height: 32px;
        background-color: white;
      "
    >
      <el-switch v-model="isDelete" />删除状态（鼠标左键单击删除元素）
    </div>
    <div
      style="
        display: flex;
        justify-content: flex-start;
        line-height: 32px;
        background-color: white;
      "
    >
      <el-switch v-model="isModify" />编辑状态
    </div>
    <div
      style="
        display: flex;
        justify-content: flex-start;
        line-height: 32px;
        background-color: white;
      "
    >
      <el-button :disabled="iconFeatureArr.length === 0" @click="scaleFn(0.02)"
        >增大图标</el-button
      >
      <el-button :disabled="iconFeatureArr.length === 0" @click="scaleFn(-0.02)"
        >减小图标</el-button
      >
    </div>

    <!--测距按钮-->
    <div style="display: flex; justify-content: flex-start">
      <el-button @click="distance()">开始测距</el-button>
      <el-button @click="cancal()">结束测距</el-button>
    </div>

    <div style="display: flex; justify-content: flex-start">
      <el-button @click="submitEdit()">保存编辑状态</el-button>
    </div>

    <!-- 按钮，触发人员轨迹查询弹窗 -->
    <!-- 人员轨迹查询弹窗 -->
    <el-dialog v-model="showGetUserPositionDialog" title="Shipping address">
      <!-- 表单，用于输入查询条件 -->
      <el-form :model="userVO">
        <el-row>
          <!-- 用户ID输入框 -->
          <el-form-item label="用户id" class="w-50 m-2">
            <el-input v-model="userVO.id" autocomplete="off" />
          </el-form-item>

          <!-- 用户姓名输入框 -->
          <el-form-item label="用户姓名" class="w-50 m-2">
            <el-input v-model="userVO.name" autocomplete="off" />
          </el-form-item>
        </el-row>
        <!-- 时间选择器，选择查询的开始和结束时间 -->
        <el-row>
          <div class="block">
            <span class="demonstration">开始时间</span>
            <el-date-picker
              v-model="userVO.startTime"
              type="datetime"
              placeholder="可以选择开始时间"
              value-format="YYYY-MM-DD HH:mm:ss"
            />
          </div>
          <div class="block">
            <span class="demonstration">结束时间</span>
            <el-date-picker
              v-model="userVO.endTime"
              type="datetime"
              placeholder="以选择结束时间"
              value-format="YYYY-MM-DD HH:mm:ss"
            />
          </div>
        </el-row>
        <!-- 是否生成路径选择 -->
        <el-row>
          <div class="mb-2 flex items-center text-sm">
            是否生成路径：
            <el-radio-group v-model="userVO.createPath" class="ml-4">
              <el-radio :label="true" size="large">是</el-radio>
              <el-radio :label="false" size="large">否</el-radio>
            </el-radio-group>
          </div>
          <!-- 如果选择生成路径，显示路径生成方式选择 -->
          <div
            class="mb-2 flex items-center text-sm"
            v-show="userVO.createPath"
          >
            请选择路径生成方式：
            <!-- 下拉框，选择路径生成方式 -->
            <el-select
              v-model="userVO.trafficMode"
              class="m-2"
              placeholder="Select"
              size="large"
              style="width: 240px"
            >
              <el-option
                v-for="item in trafficModes"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </div>
        </el-row>
      </el-form>
      <!-- 弹窗底部按钮 -->
      <template #footer>
        <span class="dialog-footer">
          <!-- 取消按钮 -->
          <el-button @click="showGetUserPositionDialog = false"
            >Cancel</el-button
          >
          <!-- 确认按钮 -->
          <el-button type="primary" @click="getUserPosition">
            Confirm
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import "ol/ol.css";
import { Map, View, Feature, Overlay } from "ol";

import { Vector as VectorLayer } from "ol/layer";
import { OSM, Vector as VectorSource } from "ol/source";
import { Point, LineString, Polygon, Circle } from "ol/geom";
import { transform, fromLonLat, toLonLat } from "ol/proj";
import XYZ from "ol/source/XYZ";
import { Icon, Fill, Stroke, Style } from "ol/style";
import OLCesium from "@/libs/olcs2.16.0/OlCesium";
import { OperationType } from "@/enums/system";
import { Cesium3DTileset } from "cesium";
import { geojsonURLs, tilesetURLs } from "@/configs/data";
import TileLayer from "ol/layer/Tile";
import dao from "@/api/dao";
import useMap from "@/hooks/useMap";
import { ref, reactive, watch, computed, onMounted, nextTick } from "vue";
import { mapCfg } from "@/configs/map";
import { OlDrawGeometryType } from "@/enums/ol";
//测距
import Draw from "ol/interaction/Draw";
import { DoubleClickZoom, Modify, Select } from "ol/interaction";
import { Circle as CircleStyle } from "ol/style";
import { getArea, getLength } from "ol/sphere";
import { unByKey } from "ol/Observable";
import { distance } from "ol/coordinate";
import { ElMessage } from "element-plus";

import "ol-ext/dist/ol-ext.css";
import Delete from "ol-ext/interaction/Delete";
// var map = null
var fill = null;
var helpTooltipElement = null;
var feature = null;
var helpTooltip = null;
var draw = null;
var measureTooltipElement = null;
var measureTooltip = null;
var listener = null;
var mapMouseMove = null;

export default {
  data() {
    return {
      scale: 0.1,
      iconFeatureArr: [],
      isDelete: false,
      isModify: false,
      delete: null,
      modify: null,
      selectedShape: "", //选中的图形
      shapeOptions: [
        // 图形选项数据
        { label: "面", value: "Polygon" },
        { label: "圆", value: "Circle" },
        { label: "线", value: "LineString" },
      ],
      selectedIcon: "", //选择的图标
      iconOptions: [
        { label: "建筑", value: "building" },
        { label: "人员", value: "person" },
      ],

      drawActivatedType: null,
      currentStatus: null,
      drawElements: [],
      drawEElements: [],
      drawLayers: [],
      is2D: true,
      user: {
        name: "刘",
      },
      // 查询到的用户列表
      userList: [],
      // 选择的用户
      selectedUser: null,
      // 用户及位置数据
      userPositionData: {},
      // 位置列表
      positionList: [],
      // 处理后的位置信息
      newPositionList: [],
      // 用户数据表单
      userVO: {
        id: "",
        startTime: "",
        endTime: "",
        pageNo: 1,
        pageSize: 100,
        createPath: false,
        trafficMode: "car",
      },
      //新增坐标数据表单
      position: {
        id: "",
        uid: "",
        lon: "",
        lat: "",
        createTime: "",
      },

      // 交通方式
      trafficModes: [
        { value: "car", label: "汽车" },
        { value: "bike", label: "自行车" },
        { value: "foot", label: "步行" },
      ],
      // dialog控制器
      showGetUserPositionDialog: false,
      showAddUserPositionDialog: false,
      path: [], // 模拟路径
      pathPoint: [],
      pathIndex: 0, // 路径点索引
      marker: {}, //移动点
      splitNumber: 20, // 每两个经纬度之间的分割点
      setIntervalTime: 300, // 移动点间隔时间
      myplanImg: "/icons/icon-right.gif", // 移动点的图片
      helpTooltipElement: {}, // 平台信息div
      helpTooltip: {}, // 平台信息overlay
      sourceFeatures: new VectorSource(),
      lineString: new LineString([]),
    };

    //绘制图形
  },
  watch: {
    isDelete(val, oldVal) {
      val && (this.isModify = false);
      if (!this.delete) {
        const delete1 = new Delete({ source: this.sourceFeatures });
        this.map.addInteraction(delete1);
        this.delete = delete1;
        return;
      }
      this.delete.setActive(val);
    },
    isModify(val, oldVal) {
      val && (this.isDelete = false);
      if (!this.modify) {
        const modify = new Modify({ source: this.sourceFeatures });
        this.map.addInteraction(modify);
        this.modify = modify;
        return;
      }
      this.modify.setActive(val);
    },
  },
  created() {
    this.drawActivatedType = ref("");
    this.currentStatus = reactive({
      mode: mapCfg.enable3DImmediately,
      operation: OperationType.NONE,
    });
    this.lineString.setCoordinates([
      [121.62021584789193, 29.9239055235632],
      [121.62021584789193, 29.9239055235632],
    ]);
  },

  mounted() {
    // this.initSeamap();
    this.initMap();
    setTimeout(() => {
      this.initEditData();
    }, 1000);
  },
  methods: {
    submitEdit() {
      const features = this.sourceFeatures.getFeatures();

      // 初始化四个字段用于保存不同类型的要素数据
      const pointFeatures = [];
      const lineFeatures = [];
      const polygonFeatures = [];
      const circleFeatures = [];

      // 遍历要素数据
      features.forEach((feature) => {
        const geometry = feature.getGeometry();
        const coordinates = geometry.getCoordinates();
        const properties = feature.getProperties();

        // 根据要素的几何类型进行分类
        if (geometry.getType() === "Point") {
          pointFeatures.push({ geometry: coordinates, properties });
        } else if (geometry.getType() === "LineString") {
          lineFeatures.push({ geometry: coordinates, properties });
        } else if (geometry.getType() === "Polygon") {
          polygonFeatures.push({ geometry: coordinates, properties });
        } else if (geometry.getType() === "Circle") {
          console.log("Circle--", geometry);
          circleFeatures.push({ geometry: coordinates, properties });
        }
      });

      console.log("pointFeatures:", pointFeatures);
      console.log("lineFeatures:", lineFeatures);
      console.log("polygonFeatures:", polygonFeatures);
      console.log("circleFeatures:", circleFeatures);

      // 将分类后的数据保存在本地存储中
      localStorage.setItem("pointFeatures", JSON.stringify(pointFeatures));
      localStorage.setItem("lineFeatures", JSON.stringify(lineFeatures));
      localStorage.setItem("polygonFeatures", JSON.stringify(polygonFeatures));
      localStorage.setItem("circleFeatures", JSON.stringify(circleFeatures));

      ElMessage({
        message: "保存成功！",
        type: "success",
      });
    },
    scaleFn(flag) {
      this.scale += flag;
      if (this.scale < 0.02) {
        this.scale = 0.02;
      }
      const scale = this.scale;
      console.log(scale, "scale");
      this.iconFeatureArr.map((feature) => {
        feature.setStyle(
          new Style({
            image: new Icon({
              src: feature.get("iconSrc"),
              scale, // 可根据需要调整图标大小
            }),
          })
        );
      });
    },
    map2DTO3D() {
      // 判断当前地图状态并切换
      if (this.is2D) {
        this.map3d.setEnabled(true);
        this.is2D = false;
      } else {
        this.map3d.setEnabled(false);
        this.is2D = true;
      }
    },
    // 将切分的点与原数据对应
    newPositionData() {
      let i = 0;
      let newPositions = [];

      for (let i = 0, j = 0; i < this.positionList.length; i++) {
        let e = this.positionList[i];
        if (j < this.path.length) {
          if (this.path[j][0] != e.lon || this.path[j][1] != e.lat) {
            let position = {
              createTime: e.createTime,
              lon: e.lon,
              lat: e.lat,
            };
            newPositions.push(position);
            j++;
            i--;
          } else {
            newPositions.push(e);
          }
        } else {
          newPositions.push(e);
        }
      }
      this.positionList = newPositions;
    },

    openPositionDialog() {
      // 判断是否选中用户
      if (this.selectedUser == null) {
        ElMessage({
          message: "请先查询并选择用户后使用",
          type: "warning",
        });
        return;
      }

      this.reSetUserVO();
      let name = "";
      this.userList.forEach((e) => {
        if (e.id === this.selectedUser) {
          name = e.name;
        }
      });

      // 设置表单基础属性
      this.userVO.id = this.selectedUser;
      this.userVO.name = name;
      this.showGetUserPositionDialog = true;
    },

    //出发新增人员信息的弹窗
    openAddUserPositionDialog() {
      this.showAddUserPositionDialog = true;
    },

    // 重置userVO
    reSetUserVO() {
      this.userVO = this.$options.data().userVO;
    },

    // 获得用户位置记录
    getUserPosition() {
      // 关闭dialog
      this.showGetUserPositionDialog = false;
      // 清除旧数据
      this.userPositionData = null;

      // 请求用户位置信息
      dao.getUserPosition(this.userVO).then((response) => {
        var data = response.data.data;
        this.userPositionData = data;
        this.positionList = data.positions;
        this.showMsg(response);
        this.path = [];
        // 根据位置点生成路径信息
        this.positionList.forEach((e) => {
          this.path.push([e.lon, e.lat]);
        });

        if (this.path.length > 1) {
          // 清除绘制的图层
          this.sourceFeatures.clear();
          let olLyrs = this.map.getOverlays().getArray();
          let olLyrsLength = this.map.getOverlays().getArray().length;
          for (let i = 0; i < olLyrsLength; i++) {
            olLyrs[i].setPosition(undefined);
          }
          // 初始化轨迹
          this.analysisPath(this.splitNumber);
          this.newPositionData();
          this.initSeamap();
        } else {
          alert("位置信息不足，请更换查询条件");
        }
      });
    },
    //添加用户信息
    addUserPosition() {
      dao.addPositionData(this.position).then((response) => {
        var data = response.data.data;

        console.log(data);
        this.showMsg(response);
      });
    },

    // 获得用户信息
    getUser() {
      // 将用户列表和选定用户设置为null，进行初始化
      this.userList = null;
      this.selectedUser = null;
      // 调用 dao.getUser 方法，该方法返回一个 Promise
      dao.getUser(this.user).then((response) => {
        // 处理从服务器返回的响应数据
        var data = response.data.data;
        // 使用从服务器获取的数据更新用户列表
        this.userList = data;
        this.showMsg(response);
      });
    },

    // 显示消息弹窗
    showMsg(response) {
      this.$message({
        message: response.data.msg,
        type: response.data.code == 200 ? "success" : "error",
      });
    },
    // 加载3d地图数据
    load3DTilesetToCesiumScene(url, options) {
      Cesium3DTileset.fromUrl(url)
        .then((tileset) => {
          // Custom properties
          if (!tileset.costomProps) {
            tileset.costomProps = {};
          }
          for (const key in options.properties) {
            if (Object.hasOwnProperty.call(options.properties, key)) {
              tileset.costomProps[key] = options.properties[key];
            }
          }

          // 设置偏移量（heightOffset）
          let translation = new Cesium.Cartesian3(
            0,
            0,
            options.heightOffset || 0
          );
          let modelMatrix = Cesium.Matrix4.fromTranslation(translation);

          tileset.modelMatrix = modelMatrix;

          this.map3d.getCesiumScene().primitives.add(tileset);
          options.flyTo && this.map3d.getCesiumViewer().flyTo(tileset);
        })
        .catch((error) => {
          console.error(`Error loading tileset: ${error}`);
        });
    },
    // 初始化地图
    initMap() {
      this.map = new Map({
        target: "map",
        view: new View({
          projection: "EPSG:4326",
          center: [121.62021584789193, 29.9239055235632],
          zoom: 15,
          minZoom: 3, // 限制最大显示
          maxZoom: 19,
        }),
        layers: [
          new TileLayer(),
          new TileLayer({
            source: new XYZ({
              url: "http://localhost:8084/map/Tiles/{z}/{x}/{y}.png",
              // url: "http://localhost:5500/Tiles/{z}/{x}/{y}.png",
              // url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}",
              wrapX: false,
            }),
          }),
          new VectorLayer({
            // 两点之间的连线
            source: new VectorSource({
              features: [
                new Feature({
                  geometry: this.lineString,
                }),
              ],
            }),
            style: [
              new Style({
                stroke: new Stroke({
                  width: 3,
                  color: "rgba(0, 0, 0, 1)",
                  lineDash: [0.1, 5],
                }),
                zIndex: 2,
              }),
            ],
            updateWhileAnimating: true,
          }),
          new VectorLayer({
            // 两端点Feature
            source: this.sourceFeatures,
          }),
        ],
      });
      // 监听单击事件
      // this.map.on("singleclick", function (e) {
      //   alert(e.coordinate);
      // });

      // 创建一个OLCesium的实例，并传递你的OpenLayers地图对象和imageryProvider作为参数
      this.map3d = new OLCesium({
        map: this.map,
      });
      this.map3d.setEnabled(false); // 禁用3D视图
      tilesetURLs.forEach((cfg) => {
        this.load3DTilesetToCesiumScene(cfg.url, {
          properties: cfg.properties,
          flyTo: true,
          heightOffset: -55,
        });
      });
    },

    // 初始化编辑的数据
    initEditData() {
      // 从本地存储中获取分类后的要素数据
      const pointFeatures =
        JSON.parse(localStorage.getItem("pointFeatures")) || [];
      const lineFeatures =
        JSON.parse(localStorage.getItem("lineFeatures")) || [];
      const polygonFeatures =
        JSON.parse(localStorage.getItem("polygonFeatures")) || [];
      const circleFeatures =
        JSON.parse(localStorage.getItem("circleFeatures")) || [];

      console.log("🚀 ~ initEditData ~ pointFeatures:", pointFeatures);
      console.log("🚀 ~ initEditData ~ lineFeatures:", lineFeatures);
      console.log("🚀 ~ initEditData ~ pointFeatures:", polygonFeatures);
      console.log("🚀 ~ initEditData ~ pointFeatures:", circleFeatures);

      // 点
      const popint_features = pointFeatures.map((point) => {
        const feature = new Feature({
          geometry: new Point(point.geometry),
        });
        if (point.properties.iconSrc) {
          feature.setStyle(
            new Style({
              image: new Icon({
                src: point.properties.iconSrc,
                scale: this.scale,
              }),
            })
          );

          feature.set("iconSrc", point.properties.iconSrc);
        }
        this.iconFeatureArr.push(feature);
        return feature;
      });
      this.sourceFeatures.addFeatures(popint_features);
      const popint_vector = new VectorLayer({
        source: this.sourceFeatures,
      });

      this.map.addLayer(popint_vector);

      // 线
      const line_features = lineFeatures.map((line) => {
        const feature = new Feature({
          geometry: new LineString(line.geometry),
        });
        return feature;
      });
      this.sourceFeatures.addFeatures(line_features);
      const line_vector = new VectorLayer({
        source: this.sourceFeatures,
      });

      this.map.addLayer(line_vector);

      // 面
      const polygon_features = polygonFeatures.map((polygon) => {
        const feature = new Feature({
          geometry: new Polygon(polygon.geometry),
        });
        return feature;
      });
      this.sourceFeatures.addFeatures(polygon_features);
      const polygon_vector = new VectorLayer({
        source: this.sourceFeatures,
      });

      this.map.addLayer(polygon_vector);

      // 圆，数据跟其他的不一样，初始化也不一样
      const circle_features = circleFeatures.map((circle) => {
        const centers = circle.properties?.geometry?.flatCoordinates;
        // 计算圆的半径
        const radius = Math.sqrt(
          Math.pow(centers[0] - centers[2], 2) +
            Math.pow(centers[1] - centers[3], 2)
        );
        const center = [centers[0], centers[1]]; // 圆中心点
        const feature = new Feature({
          geometry: new Circle(center, radius),
        });
        return feature;
      });
      this.sourceFeatures.addFeatures(circle_features);
      const circle_vector = new VectorLayer({
        source: this.sourceFeatures,
      });

      this.map.addLayer(circle_vector);
    },

    // 初始化轨迹
    initSeamap: function () {
      this.pathIndex = this.path.length - 1;
      this.marker = new Overlay({
        positioning: "center-center",
        offset: [0, 0],
        element: document.getElementById("geo-marker"),
        stopEvent: false,
      });
      this.map.addOverlay(this.marker);
      let style1 = [
        // 开始结束点样式
        new Style({
          image: new Icon({
            src: "/icons/destination.png",
            scale: 0.03,
            anchor: [0.5, 0.5],
          }),
        }),
      ];
      let feature_start = new Feature({
        geometry: new Point(this.path[0]),
      });
      let feature_end = new Feature({
        geometry: new Point(this.path[this.path.length - 1]),
      });
      feature_start.setStyle(style1);
      feature_end.setStyle(style1);
      this.sourceFeatures.addFeatures([feature_start, feature_end]);
      this.lineString.setCoordinates(this.path);
      this.helpTooltipElement = document.createElement("div");
      this.helpTooltipElement.className = "measuretip";
      this.helpTooltipElement.id = "speed";
      this.helpTooltip = new Overlay({
        element: this.helpTooltipElement,
        offset: [15, 0],
        positioning: "center-left",
      });
      this.map.addOverlay(this.helpTooltip);
      this.map.once("postcompose", (event) => {
        setInterval(() => {
          this.animation();
        }, this.setIntervalTime);
      });
    },
    animation: function () {
      if (this.pathIndex === -1) {
        this.pathIndex = this.path.length - 1;
      }

      // 获取前一个点的坐标
      const prevPoint =
        this.path[this.pathIndex + 1] || this.path[this.pathIndex];

      // 设置图标的位置
      this.marker.setPosition(this.path[this.pathIndex]);

      // 判断 X 轴的增减关系
      if (this.path[this.pathIndex][0] > prevPoint[0]) {
        // X 轴增大，使用 1 号 GIF 图片
        this.myplanImg = "/icons/icon-right.gif";
      } else if (this.path[this.pathIndex][0] < prevPoint[0]) {
        // X 轴减小，使用 2 号 GIF 图片
        this.myplanImg = "/icons/icon-left.gif";
      }
      // 如果 X 轴不变，则保持默认 GIF 图片

      // 设置提示信息的内容和位置
      const currentCoordinate = this.path[this.pathIndex];
      this.updateTooltipContent(currentCoordinate);

      // 更新路径索引
      this.pathIndex--;
      if (this.pathIndex < 0) {
        // 动画结束，执行一些结束逻辑
      } else {
        // 在动画步骤中添加额外的逻辑，更新动画时显示的坐标信息
        const currentCoordinate = this.path[this.pathIndex];
        this.updateTooltipContent(currentCoordinate);
      }
    },

    analysisPath: function (splitNumber) {
      let tempPath = [...this.path];

      let pathResults = [];
      let tempPoint = [0, 0];
      if (tempPath.length > 1) {
        for (let i = 0; i < tempPath.length - 1; i++) {
          // 每两个点之间分割出splitNumber个点
          pathResults.push(tempPath[i]);
          for (let j = 0; j < splitNumber; j++) {
            tempPoint[0] =
              ((tempPath[i + 1][0] - tempPath[i][0]) * (j + 1)) / splitNumber +
              tempPath[i][0];
            tempPoint[1] =
              ((tempPath[i + 1][1] - tempPath[i][1]) * (j + 1)) / splitNumber +
              tempPath[i][1];
            pathResults.push([...tempPoint]);
          }
        }
        pathResults.push(tempPath[tempPath.length - 1]);
        this.path = [...pathResults];
      }
    },

    updateTooltipContent(coordinate) {
      // 更新提示信息的内容和位置
      this.helpTooltipElement.innerHTML =
        "<B>名称：</B>王某" +
        "<br>" +
        "<B>经纬度：</B>" +
        (coordinate[0] + "").substring(0, 8) +
        "," +
        (coordinate[1] + "").substring(0, 8);

      this.helpTooltip.setPosition(coordinate);

      // 如果希望在控制台输出实时坐标，可以添加下面这行代码
      //console.log("实时坐标:", coordinate);
    },

    // 测距
    distance() {
      let source = new VectorSource(); // 创建一个数据源，用来放置绘制过程中和绘制结束后的线段
      const layer = new VectorLayer({
        // 添加一个图层，用来放置数据源
        source: source,
        style: new Style({
          fill: new Fill({
            color: "rgba(255, 255, 255, 0.2)",
          }),
          stroke: new Stroke({
            color: "#ffcc33",
            width: 4,
          }),
          image: new CircleStyle({
            radius: 7,
            fill: new Fill({
              color: "#ffcc33",
            }),
          }),
        }),
      });

      mapMouseMove = this.map.on("pointermove", (ev) => {
        let helpMsg = "点击开始测量";
        if (feature) {
          helpMsg = "双击结束测量";
        }
        helpTooltipElement.innerHTML = helpMsg;
        helpTooltip.setPosition(ev.coordinate);
        helpTooltipElement.classList.remove("hidden");
      });

      this.map.getViewport().addEventListener("mouseout", function () {
        helpTooltipElement.classList.add("hidden");
      });
      //鼠标绘制线
      draw = new Draw({
        source,
        type: "LineString",
        style: new Style({
          fill: new Fill({
            color: "rgba(255, 255, 255, 0.2)",
          }),
          stroke: new Stroke({
            color: "rgba(0, 0, 0, 0.5)",
            lineDash: [10, 10],
            width: 4,
          }),
          image: new CircleStyle({
            radius: 5,
            stroke: new Stroke({
              color: "rgba(0, 0, 0, 0.7)",
            }),
            fill: new Fill({
              color: "rgba(255, 255, 255, 0.2)",
            }),
          }),
        }),
      });

      // 监听绘制
      draw.on("drawstart", (evt) => {
        let map1 = this.map;
        feature = evt.feature;
        // 显示起始测量提示
        helpTooltipElement.innerHTML = "点击开始测量";
        helpTooltip.setPosition(evt.coordinate);
        helpTooltipElement.classList.remove("hidden");

        let tooltipCoord = evt.coordinate;

        listener = feature.getGeometry().on("change", function (evt) {
          const geom = evt.target;
          let output = formatLength(geom, map1);
          tooltipCoord = geom.getLastCoordinate();
          measureTooltipElement.innerHTML = output;
          measureTooltip.setPosition(tooltipCoord);
        });
      });

      // 双击绘制完成
      draw.on("drawend", () => {
        measureTooltipElement.className = "ol-tooltip ol-tooltip-static";
        measureTooltip.setOffset([0, -7]);
        feature = null;
        measureTooltipElement = null;
        this.createMeasureTooltip();
        unByKey(listener);
      });

      // 格式化长度
      const formatLength = function (line, map) {
        var sourceProj = map.getView().getProjection(); //获取投影坐标系
        var length = getLength(line, {
          projection: sourceProj /*, radius: 6371008.8*/,
        });

        let output;
        if (length > 100) {
          output = Math.round((length / 1000) * 100) / 100 + " " + "km";
        } else {
          output = Math.round(length * 100) / 100 + " " + "m";
        }
        return output;
      };

      this.createHelpTooltip();
      this.createMeasureTooltip();
      this.map.addLayer(layer);
      this.drawLayers.push(layer);
      this.map.addInteraction(draw);
    },

    // 取消绘制
    cancal() {
      for (let i = 0; i < this.drawLayers.length; i++) {
        this.map.removeLayer(this.drawLayers[i]);
      }
      for (let i = 0; i < this.drawElements.length; i++) {
        this.map.removeOverlay(this.drawElements[i]);
      }
      this.drawLayers = [];
      this.drawElements = [];
      this.map.removeInteraction(draw);
      unByKey(mapMouseMove);
    },

    createMeasureTooltip() {
      if (measureTooltipElement) {
        measureTooltipElement.parentNode.removeChild(measureTooltipElement);
      }
      measureTooltipElement = document.createElement("div");
      measureTooltipElement.className = "ol-tooltip ol-tooltip-measure";
      measureTooltip = new Overlay({
        element: measureTooltipElement,
        offset: [0, -15],
        positioning: "bottom-center",
        stopEvent: false,
        insertFirst: false,
      });
      this.drawEElements.push(measureTooltip);
      this.map.addOverlay(measureTooltip);
    },

    createHelpTooltip() {
      if (helpTooltipElement) {
        helpTooltipElement.parentNode.removeChild(helpTooltipElement);
      }
      helpTooltipElement = document.createElement("div");
      helpTooltipElement.className = "ol-tooltip hidden";
      helpTooltip = new Overlay({
        element: helpTooltipElement,
        offset: [15, 0],
        positioning: "center-left",
      });
      this.map.addOverlay(helpTooltip);
    },

    //在二维图像上进行绘制
    drawIn2d(type, fillColor) {
      const draw = new Draw({
        source: this.sourceFeatures,
        type: type,
      });
      this.map.addInteraction(draw);

      // 监听开始绘制事件
      draw.on("drawstart", (evt) => {
        console.log("开始绘制");
        console.log(evt);
      });

      // 监听结束绘制事件
      draw.on("drawend", (evt) => {
        console.log("结束绘制");
        console.log(evt);
        // 获取绘制的要素
        const feature = evt.feature;
        // 获取绘制的几何体
        const geometry = evt.feature.getGeometry();

        // 设置要素的样式
        feature.setStyle(
          new Style({
            fill: new Fill({
              color: fillColor,
            }),
            stroke: new Stroke({
              color: "black",
              width: 1,
            }),
          })
        );

        // 移除绘制交互
        this.map.removeInteraction(draw);
      });

      // 移除双击缩放地图功能，使双击只用来结束绘制功能
      const dblClickInteraction = this.map
        .getInteractions()
        .getArray()
        .find((interaction) => {
          return interaction instanceof DoubleClickZoom;
        });
      this.map.removeInteraction(dblClickInteraction);
    },

    //更新状态
    updateStatus(status) {
      Object.assign(this.currentStatus, status);
    },

    addLayerToMap(layer) {
      // 避免添加重复的图层
      let isExisting = false;
      const layers = this.map.getAllLayers();
      layers.forEach((lyr) => {
        if (layer == lyr) {
          isExisting = true;
        }
      });
      if (!isExisting) {
        this.map.addLayer(layer);
      }
    },

    //新增添加图标
    drawIconIn2d(iconType) {
      let iconSrc = ""; //存储图片的路径
      //根据图片类型不同选择不同的图片

      switch (iconType) {
        case "building":
          iconSrc = "/icons/destination.png";
          break;
        case "person":
          iconSrc = "/icons/icon.gif";
          break;
        default:
          //默认图标
          iconSrc = "/icons/destination.png";
      }

      const draw = new Draw({
        source: this.sourceFeatures,
        type: "Point", // 点标记类型
        // 不需要设置样式，因为在绘制结束后会为要素设置样式
      });
      this.map.addInteraction(draw);

      // 监听开始绘制事件
      draw.on("drawstart", (evt) => {
        console.log("开始绘制");
        console.log(evt);
      });

      // 监听结束绘制事件
      draw.on("drawend", (evt) => {
        console.log("结束绘制");
        console.log(evt);
        // 获取绘制的要素
        const feature = evt.feature;
        // 设置要素的样式
        feature.setStyle(
          new Style({
            image: new Icon({
              src: iconSrc,
              scale: this.scale, // 可根据需要调整图标大小
            }),
          })
        );
        feature.set("iconSrc", iconSrc);
        this.iconFeatureArr.push(feature);
        // 移除绘制交互
        this.map.removeInteraction(draw);

        //更新状态码
        //this.updateStatus({ status: "图标绘制完成" });
      });

      // 移除双击缩放地图功能，使双击只用来结束绘制功能
      const dblClickInteraction = this.map
        .getInteractions()
        .getArray()
        .find((interaction) => {
          return interaction instanceof DoubleClickZoom;
        });
      this.map.removeInteraction(dblClickInteraction);
    },
  },
};
</script>

<style>
.measuretip {
  position: relative;
  background-color: #f4f6f8;
  opacity: 0.5;
  border-radius: 3px;
  padding: 10px;
  font-size: 12px;
  cursor: default;
}

.position-form {
  display: flex;
  flex-direction: column;
}

.form-row {
  margin-bottom: 10px;
  display: flex;
  align-items: center;
}

.form-row label {
  margin-right: 10px;
}
</style>

<style lang="less" scoped>
/deep/.ol-tooltip {
  position: relative;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 4px;
  color: white;
  padding: 4px 8px;
  opacity: 0.7;
  white-space: nowrap;
  font-size: 12px;
  cursor: default;
  user-select: none;
}

/deep/.ol-tooltip-measure {
  opacity: 1;
  font-weight: bold;
}

/deep/.ol-tooltip-static {
  background-color: #ffcc33;
  color: black;
  border: 1px solid white;
}

/deep/.ol-tooltip-measure:before,
/deep/.ol-tooltip-static:before {
  border-top: 6px solid rgba(0, 0, 0, 0.5);
  border-right: 6px solid transparent;
  border-left: 6px solid transparent;
  content: "";
  position: absolute;
  bottom: -6px;
  margin-left: -7px;
  left: 50%;
}

/deep/.ol-tooltip-static:before {
  border-top-color: #ffcc33;
}
</style>
